﻿#include "DataAnalyzer.h"
HWND hConsole = NULL;
int CurrentWindow = WD_DESKTOP;


void Show(int GOTO) {
	switch (GOTO) {
	case WD_DESKTOP: {
		system("cls");
		cout << "使用说明:按键以选择操作,按ENTER以确定" << endl;
		cout << "统一单位:" << units << endl;
		cout << "\n\n操作:              状态:" << endl;
		cout << "1.录入数据         ";
		(__dList.point.size() > 0) ? cout << "已有数据录入" << endl : cout << "未录入" << endl;
		cout << "2.修改与删除数据  ";
		(__dList.point.size() <= 0) ? cout << " 暂无数据可以修改" << endl : cout << endl;
		cout << "3.设置仪器误差    ";
		(!devicError && !devicMiniDivison) ? cout << " 未录入" << endl : cout << " 已有数据录入" << endl  ;
		//cout << "当前为: " <<  SetPercision((devicError)? devicError : devicError ,percision) << endl;
		cout << "4.一条龙计算服务     ";
		cout << "\n选择操作并输入序号:";
		break;
	}
	default: break;
	}
}

void DesktopCallback(char a) {
	switch (a) {
	case '1': {
		if (__dList.point.size() > 0) {
			cout << "请在弹出式对话框中选择\n";
			int ret = ::MessageBox(hConsole, "已有数据,是否继续添加？", "system",  MB_YESNO | MB_ICONQUESTION| MB_TOPMOST);
			if (ret != IDYES) return;
			SetFocus(hConsole);

		}
		string n_input;
		int n = 0;
		cout << "\n要输入多少组数据(输入-1返回主菜单): "; cin >> n_input;
		if (!isNum(n_input)) { ColorPrint("乱输数据，牢大很生气", CP_RED, CP_WHITE); pause(); return; }
		n = stold(n_input);
		if (n < 1 && n!= -1) {
			ErrorBox(hConsole, "未定义输入"); //cout << "ERROR:The length of list must above 1!!!\n错误：请重新输入数值" << endl;
			return;
		}
		n = stold(n_input);

		string strInput; ld buffer;

		int size_begin = __dList.point.size();
		for (int i = size_begin; i < size_begin + n; i++) {
			jump:
			cout << "数据 " << i + 1 << "为: "; cin >> strInput;
			if (!isNum(strInput)) {
				ColorPrint("请不要输入单位等非数字字符,请重新输入", CP_RED, CP_WHITE);
				goto jump;
			}
			
			try {
				buffer = stold(strInput);
			}
			catch (const invalid_argument& e) {
				reBuildStr(strInput);
				ErrorBox(hConsole,"转型异常" );
				cout << e.what() << endl;
			}
			catch (const out_of_range& e) {
				cout << e.what() << endl;
			}
			
			__dList.point.push_back(buffer);
		}
		//MessageBox(hConsole,"数据录入完成","system",MB_ICONINFORMATION|MB_OK);
		cout << "数据录入完成" << endl;
		__dList.sort();
		pause();
		CurrentWindow = WD_DESKTOP;
		return;
	}

	case '2': {
		CurrentWindow = WD_MODIFYDATA;
		return;
	}

	case '3': {
		CurrentWindow = WD_MODIFYDIVISON;
		return;
	}

	case '4': {
		CurrentWindow = WD_CALCULATION;
		return;
	}
	default:return;
	}

}

void ModifyDataCallback() {
	 int input; ld newData; string n_input;
	label:
	cout << "要修改数据请输入1,要删除数据请输入2(输入-1返回主菜单): "; cin >> input;
	switch (input) {
	case 1: {
		while (true) {
			__dList.Print();
			cout << "要修改第几项: "; cin >> n_input;
			if (isNum(n_input) == false) {
				ErrorBox(hConsole, "无法识别");
				//cout << "无法识别";
				goto label;
			}
			int n = stold(n_input);
			cout << "修改第" << n << "项为: "; cin >> newData;
			if (__dList.Modify(n, newData) == false) return;
			cout << "请在弹出式对话框中选择\n";
			int ret = ::MessageBox(hConsole, "是否继续修改", "system", MB_YESNO | MB_ICONQUESTION| MB_TOPMOST);
			if (ret == IDNO)  return;
			SetFocus(hConsole);
		}
		return;
	}
	case 2: {
		while (true) {
			__dList.Print();
			cout << "要删除第几项: "; cin >> n_input;
			if (isNum(n_input) == false) {
				ErrorBox(hConsole, "无法识别");
				//cout << "无法识别";
				goto label;
			}
			int n = stold(n_input);
			if (__dList.DeleteElement(n) == false) { ErrorBox(hConsole, "找不到项"); return; }
			cout << "请在弹出式对话框中选择\n";
			int ret = ::MessageBox(hConsole, "是否继续修改", "system", MB_YESNO | MB_ICONQUESTION| MB_TOPMOST);
			if (ret == IDNO)  return;
			SetFocus(hConsole);
		}
		return;
	}
	case -1: {
		CurrentWindow = WD_DESKTOP;
		return;
	}
	default: {
		ErrorBox(hConsole, "未定义输入");
		//cout << "未定义输入";
		return;
	}
	}

	

}

void ModifyDivisonCallback() {
	ld n = 0.000f;
	string n_input;
	label:
	cout << "请输入仪器最小分度值:(输入-1返回主菜单): "; cin >> n_input;

	if (isNum(n_input) == false) {
		ErrorBox(hConsole, "无法识别,请检查是否输入了单位等字母");
		SetFocus(hConsole);
		goto label;
	}
	else n = stold(n_input);

	if (n == -1.0l) return;
	devicMiniDivison = n;

	cout << "请在弹出式对话框中选择\n";
	int ret = ::MessageBox(hConsole, "仪器刻度是否连续？", "system", MB_ICONQUESTION | MB_YESNO | MB_TOPMOST);
	isScaleContinuous = (ret == IDYES) ? true : false;

	cout << "设置成功" << endl;
	label2:
	cout << "\n\n更精确的仪器误差录入\n说明:\n若题目提供了更精确的仪器误差,请录入,录入非0值后,将不以分度值标准近似衡量误差。\n若无,请输入0: ";
	n_input.clear();
	cin >> n_input;

	if (isNum(n_input) == false) {
		ErrorBox(hConsole, "无法识别,请检查是否输入了单位等字母");
		SetFocus(hConsole);
		goto label2;
	}
	else devicError = stold(n_input);
	cout << "设置成功" << endl;
	pause();
	//MessageBox(hConsole,"设置成功","system",MB_OK|MB_ICONINFORMATION);
}

void calcCallback() {
	system("cls");
	if (__dList.point.size() == 0) {
		ColorPrint("错误:数据为空", CP_RED, CP_WHITE);
		pause();
		return;
	}
	if (devicError == 0.0l && devicMiniDivison == 0.0l) {
		ColorPrint("警告:仪器误差没有录入", CP_RED, CP_WHITE);
	}
	cout << "所有数据为: " << endl;
	__dList.Print(true);
	ColorPrint("数据检查完成", CP_GREEN, CP_WHITE);
	
	ld _uA = __dList.uA(), _uB = __dList.uB();
	string avrg = SetPercision(__dList.Average(), percision),
		   uA = SetPercision(_uA, percision) , uB = SetPercision(_uB, percision),
		   uncertainty = SetPercision(sqrt(_uA * _uA + _uB * _uB), percision );
	cout << "\n平均值为: " << avrg << units << endl;
	cout << "标准差为: " << SetPercision(__dList.StandardDeviation(),percision) << units << endl;
	cout << "DeltaA为: " << uA << units << endl;
	cout << "DeltaB为: " << uB << units << endl;
	cout << "总不确定度DeltaX为: " << uncertainty << units << endl;
	cout << "结果表示为: " << avrg << " +- " << uncertainty << units << endl;

	cout << "\n\n数据排序: " << endl;
	__dList.sort();
	__dList.Print();
	pause();

}

char a = '\0';

int main() {
	hConsole = GetConsoleWindow();
	start:
	system("cls");
	cout << "\nCopyright (c) FZU Siyuan Deng 邓思源 2024 version 1.0.0.1\nImportant Statement:" << endl;
	cout << "Some of the calculation factors in the program are from Student Experiment Textbook which is approximate.\nDon't use this program for professional scientific analysis" << endl;
	string s_input;
	cout << "\n\n使用程序前请先设置精度\n该实验要保留几位有效小数(四舍六入五双法则)(保留3位小数就输入3): "; cin >> s_input;
	if (!isNum(s_input)) { ColorPrint("乱输数据，牢大很生气", CP_RED, CP_BLACK); pause(); goto start; }
	percision = stold(s_input);
	cout << "\n请输入测量单位(example:mm): ";
	cin >> units;
begin:
	system("color f0");
	SetFocus(hConsole);
	Show(CurrentWindow);
	while (a = getchar()) {
		switch (CurrentWindow) {
		case WD_DESKTOP: {
			DesktopCallback(a);
			goto begin;
		}
		case WD_MODIFYDATA: {
			ModifyDataCallback();
			CurrentWindow = WD_DESKTOP;
			goto begin;
		}
		case WD_MODIFYDIVISON: {
			ModifyDivisonCallback();
			CurrentWindow = WD_DESKTOP;
			goto begin;
		}

		case WD_CALCULATION: {
			calcCallback();
			CurrentWindow = WD_DESKTOP;
			goto begin;
		}
		}

	}
	
	return 0;
}